Глава 02
Вверх
Прежде чем начинать строить параметризованные контейнерные классы,
Общая форма декларации параметризованного класса приведена ниже:
Здесь Ttype представляет собой имя типа шаблона, которое в каждом случае
Создав параметризованный класс, вы можете создать конкретную реализацию
Здесь type представляет собой имя типа данных, над которыми фактически
Наконец функции-члены параметризованного класса автоматически являются
Вверх
Простейшим примером контейнерного класса является ограниченный или
Перегрузка оператора []
В С++ оператор [] при перегрузке считается бинарным оператором.
Чисто технически, параметр не обязательно должен принадлежать к типу int
Принцип работы оператора [] проще всего понять на примере объекта
Индекс этого массива будет транслироваться в следующий вызов функции
Таким образом выражение, используемое в качестве оператора индексации,
Функцию operator[]() можно разработать таким образом, чтобы оператор []
Построение параметризованного ограниченного массива
Нижеприведенная программа создает параметризованный ограниченный массив и
#include<iostream.h>
//параметризированный класс ограниченного массива
template <class Atype> class atype
//конструктор для atype
//обеспечение диапазона проверки для atype
main()
cout << "Int array:";
return 0;
Результат:
Int array:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
7 18 19
Double array:0 3.14 6.28 9.42 12.56 15.7 18.84 21.98 25.12 28.26 31.4
34.54 37.68 40.82 43.96 47.1 50.24 53.38 56.52 59.66
Значение с индексом 45 Выходит за пределы диапазона
Эта программа реализует параметризованный тип защищенного массива,
Как показывает этот пример параметризованные классы позволяют
Принцип работы программы таков: Пространство для массива выделяется
Размер массива передается в качестве параметра
Таким образом, вы должны указывать размер массива при его создании.
Назад |
Начало урока |
Вверх |
Вперед
Обзор параметризованных классов
необходимо хотя бы обзорно познакомиться с шаблонами классов. Определяя
параметризованный класс, вы создаете класс, который определяет все
алгоритмы, используемые этим классом, однако фактический тип данных,
над которыми производятся манипуляции, будет указан в качестве параметра
при конкретизации объектов этого класса. Компилятор автоматически
сгенерирует соответствующий объект на основании указанного вами типа.
template<class Ttype>class class-name
{
конкретизации будет замещаться фактическим типом данных. При необходимости
вы можете определить более одного параметризованного типа данных, используя
список с разделителем - запятой. В пределах определения класса имя Ttype
можно использовать в любом месте.
этого класса, используя следующую общую форму:
class-name <type> ob;
оперирует класс, и заменяет собой переменную Ttype.
параметризованными. Их не обязательно декларировать как параметризованные
с помощью ключевого слова template.
Ограниченные массивы
защищенный массив. Как вы знаете во время выполнения кода можно выйти
за границу массива или не дойти до нее без генерации сообщений об ошибках
времени выполнения. Однако эту проблему можно успешно решить. Для этого
необходимо создать класс который содержит массив, и разрешить доступ
к массиву только через перегруженный индексирующий оператор [].
В функции operator[]() вы можете перехватывать индекс, выходящий за рамки
диапазона массива. Поскольку механизм проверки границ будет одинаков
для всех типов данных, имеет смысл создание параметризованного ограниченного
массива, который вы сможете использовать каждый раз когда вам потребуется
защищенный массив. Как вы увидите далее ограниченный параметризованный
массив является простейшим, но не смотря на это одним из наиболее полезных
контейнерных классов.
Как уже упоминалось, построение ограниченного параметризированного
массива требует перегрузки оператора []. Если вы еще не знакомы
с перегрузкой этого оператора, вам поможет материал следующего раздела.
[] может быть перегружен только функцией-членом. Общая форма функции-члена
operator[]() приведена ниже :
type class-name::operator[](int index)
{
Однако функции operator[](), как правило используются для обеспечения
индексации массивов, а для этого обычно используются целые значения.
Как правило функция operator[]() возвращает значение того же типа,
что и тип данных, хранящихся в индексируемом массиве.
с именем ob, проиндексированного следующим образом :
ob[9]
operator[]() :
operator[](9)
передается функции operator[]() как явный параметр.Указатель this
будет указывать на ob, объект, сгенерировавший этот вызов.
можно было использовать как в левой, так и в правой части оператора
присваивания. Для этого следует определить возвращаемое значение
функции operator[]() как ссылку, и возвращать ссылку на указанный
элемент массива. В этом случае будут корректны следующие типы утверждений:
ob[9] = 10;
x = ob[9]
иллюстрирует его использование. Обратите внимание что функция operator[]()
возвращает ссылку, которая позволяет использовать ее в любой части
утверждения присваивания.
//параметризированный ограниченный массив
#include<stdlib.h>
{
int length;
public:
~atype()
{delete [] a;} //деструктор встроенный
Atype &operator[](int i);
template <class Atype> atype
{
length = size;
a=new Atype[size]; //создали массив в динамической памяти
if(!a)
{
exit(1);
//инициализация нулем
for(i=0;i<size;i++) a[i]=0;
template <class Atype> Atype &atype<Atype>::operator [](int i)
{
{
cout << i <<" Vyhodit za predely diapazona \n";
exit(1);
return a[i];
{
atype<double> doubleob(20);//массив типа double
int i;
for(i=0;i<20;i++) intob[i]=i;
for(i=0;i<20;i++) cout << intob[i] << " ";
cout << endl;
cout << " Double array:";
for(i=0;i<20;i++) doubleob[i]=(double)i*3.14;
for(i=0;i<20;i++) cout << doubleob[i] << " ";
cout << endl;
intob[45]=100;//generate run-time error
а затем демонстрирует его использование, создавая массив целых и
массив переменных типа double.(Можно попытаться создать и массивы других
типов).
один раз написать и отладить код, который после этого можно использовать
с данными любых типов без необходимости его дальнейшей переработки
для каждого конкретного приложения.
динамически, а соответствующий указатель на этот адрес памяти хранится
в переменной a.
a=new Atype[size]; //создали массив в динамической памяти
конструктору atype и хранится в переменной lenght.
template <class Atype> atype <Atype>::atype(int size)
{
length = size;
. . .
Поскольку создавать можно массивы всевозможных размеров, atype можно
применять в самом широком диапазоне приложений. Однако, если вы заведомо
знаете, что будете работать с массивами одного размера, рекомендуется
использвать для atype массивы фиксированной длины, так как это
несколько ускорит время выполнения.
Содержание